﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VehicleScale.Models;
using VehicleScale.EntityMappers;
using System.Diagnostics;

namespace VehicleScale.DataAccess
{
    public class CustomerDataAccess : BaseDataAccess, ICustomerDataAccess
    {

        #region Properties

        private CustomerModel _searchObject;
        /// <summary>
        /// Search Object Property
        /// </summary>
        public CustomerModel SearchObject
        {
            get { return _searchObject; }
            set
            {
                if (_searchObject != value)
                {
                    _searchObject = value;
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Search Method
        /// </summary>
        /// <returns></returns>
        public IList<CustomerModel> Searcher()
        {
            IList<CustomerModel> collection;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                IQueryable<Customer> query = dataContext.Customers;
                if (!String.IsNullOrEmpty(_searchObject.CustomerID))
                {
                    query = query.Where(e => e.CustomerID.Contains(_searchObject.CustomerID));
                }
                if (!String.IsNullOrEmpty(_searchObject.CustomerName))
                {
                    query = query.Where(e => e.CustomerName.Contains(_searchObject.CustomerName));
                }
                if (!String.IsNullOrEmpty(_searchObject.Telephone))
                {
                    query = query.Where(e => e.Telephone.Contains(_searchObject.Telephone));
                }
                if (!String.IsNullOrEmpty(_searchObject.Address))
                {
                    query = query.Where(e => e.Address.Contains(_searchObject.Address));
                }
                if (!String.IsNullOrEmpty(_searchObject.FaxNumber))
                {
                    query = query.Where(e => e.FaxNumber.Contains(_searchObject.FaxNumber));
                }
                if (!String.IsNullOrEmpty(_searchObject.TaxCode))
                {
                    query = query.Where(e => e.TaxCode.Contains(_searchObject.TaxCode));
                }
                if (!String.IsNullOrEmpty(_searchObject.Identification))
                {
                    query = query.Where(e => e.Identification.Contains(_searchObject.Identification));
                }
                collection = new List<CustomerModel>();
                foreach (var item in query)
                {
                    collection.Add(CustomerMapper.ToModel(item));
                }
            }

            return collection;
        }

        /// <summary>
        /// Get all Method
        /// </summary>
        /// <returns></returns>
        public IList<CustomerModel> GetAll()
        {
            IList<CustomerModel> collection;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                IQueryable<Customer> query = dataContext.Customers;

                collection = new List<CustomerModel>();
                foreach (var item in query)
                {
                    collection.Add(CustomerMapper.ToModel(item));
                }
            }
            
            return collection;
        }

        /// <summary>
        /// Get Method
        /// </summary>
        /// <returns></returns>
        public CustomerModel Get()
        {
            CustomerModel item = null;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                Customer query = dataContext.Customers.FirstOrDefault();

                if (query != null) item = CustomerMapper.ToModel(query);
            }

            return item;
        }

        /// <summary>
        /// Get Last Method
        /// </summary>
        /// <returns></returns>
        public CustomerModel GetLast()
        {
            CustomerModel item = null;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                Customer query = dataContext.Customers.LastOrDefault();

                if (query != null) item = CustomerMapper.ToModel(query);
            }

            return item;
        }

        /// <summary>
        /// Generate Auto ID Method
        /// </summary>
        /// <param name="dataContext"></param>
        /// <returns></returns>
        private string GenerateAutoID(DataClassesDataContext dataContext)
        {
            string id = String.Empty;
            int length = 20; // length default
            string prefix = String.Empty;
            string startNumber = "1";
            string defaultID = String.Empty;

            // Create Default Key
            Config config = dataContext.Configs.FirstOrDefault();
            if (config != null)
            {
                prefix = config.CustomerPrefix;
                length = config.CustomerCodeLength;
            }
            defaultID = prefix + startNumber.PadLeft(length, '0');

            // Create Automation Key
            var query = dataContext.Customers.Where(e =>
                e.CustomerID.StartsWith(prefix));
            if (query != null)
                id = query.Max(e => e.CustomerID);

            if (String.IsNullOrEmpty(id))
                id = defaultID;
            else
            {
                id = id.Remove(0, prefix.Length);
                int numberID;
                string suffix;
                if (Int32.TryParse(id, out numberID))
                {
                    numberID++;
                    suffix = numberID.ToString().PadLeft(length, '0');
                    id = prefix + suffix;
                }
                else
                {
                    id = defaultID;
                }
            }
            return id;
        }

        /// <summary>
        /// Add Method
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Add(CustomerModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    if (String.IsNullOrEmpty(item.CustomerID))
                    {
                        item.CustomerID = GenerateAutoID(dataContext);
                    }

                    Customer entity = new Customer();
                    CustomerMapper.ToEntity(entity, item);
                    dataContext.Customers.InsertOnSubmit(entity);
                    dataContext.SubmitChanges();

                    result = true;
                    item.IsNew = false;
                    item.IsEdit = false;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        }

        public bool Add(IList<CustomerModel> collection)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Edit Item Method
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Edit(CustomerModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Customer entity = dataContext.Customers.Where(e => e.CustomerID == item.CustomerID).SingleOrDefault();
                    if (entity != null)
                    {
                        CustomerMapper.ToEntity(entity, item);
                        dataContext.SubmitChanges();
                        result = true;
                        item.IsNew = false;
                        item.IsEdit = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        }

        /// <summary>
        /// Edit collection Method
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public bool Edit(IList<CustomerModel> collection)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Delete Method
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Delete(CustomerModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Customer entity = dataContext.Customers.Where(e => e.CustomerID == item.CustomerID).SingleOrDefault();
                    if (entity != null)
                    {
                        dataContext.Customers.DeleteOnSubmit(entity);
                        dataContext.SubmitChanges();
                        result = true;
                    }
                }
                
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        }

        public bool Delete(IList<CustomerModel> collection)
        {
            throw new NotImplementedException();
        }

        #endregion

    }
}
